/*
 * Copyright (c) 2010 Mathew Hall, University of Sheffield.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following conditions
 * are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided
 * with the distribution.
 *
 * Neither the name of the University of Sheffield nor the names of its
 * contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
package primitives.graph;

import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

public class Graph implements Serializable{
	private Set<Node> nodes;

	//private HashMap<Node,Set<Transition>> transitions;
	public Graph(){
		nodes = new HashSet<Node>();
		//transitions = new HashMap<Node,Set<Transition>>();
	
	}
	/**
		transitions are calculated on the fly to avoid consistency errors; this ctor is equivalent to Graph(Set<Node>).
	*/
	@Deprecated
	public Graph(Set<Node> nodes,
			HashMap<Node, Set<Transition>> transitions) {
		this.nodes = nodes;
	}
	
	public Graph(Set<Node> nodes){
		this.nodes = nodes;
	}
	
	
	
	public Set<Node> getNodes() {
		return nodes;
	}
	public void setNodes(Set<Node> nodes) {
		this.nodes = nodes;
	}
		
	public HashMap<Node, Set<Transition>> getTransitions() {
		HashMap<Node,Set<Transition>> tx  = new HashMap<Node,Set<Transition>>();
		for(Node n: nodes){
			if(tx.get(n) == null) tx.put(n, new HashSet<Transition>());
			tx.get(n).addAll(n.getTransitionsAsT());
			
		}
		return tx;
	}
	public void setTransitions(HashMap<Node, Set<Transition>> transitions) {
		//this.transitions = transitions;
	}
	
	public void addNode(String label){
		addNode(new Node(label));
	}
	public void addNode(Node n){
		nodes.add(n);
	}
	
	public void connect(Node s, Node d){
		connect(s,d,"");
	}
	
	public void connect(Node s, Node d, String l){
		if(!nodes.contains(s)) nodes.add(s);
		if(!nodes.contains(d)) nodes.add(d);
		s.connect(d,l);
		//if(getTransitions().get(s) == null) getTransitions().put(s,new HashSet<Transition>());
		//getTransitions().get(s).add(new Transition(s,d,l));
	}

        public int countTransitions(){
            HashMap<Node,Set<Transition>> ts = getTransitions();
            int count =0;
            for(Node n : ts.keySet()){
                count += n.getTransitionsAsT().size();
            }
            return count;
        }
	
	public boolean connectivity(Node n1, Node n2){
		for(Transition t: getTransitions().get(n1))
			if(t.getDestinationNode() == n2) return true;
		return false;
	}
	@Override
	public String toString() {
		return "Graph [nodes={" + nodes + "}, transitions={" + getTransitions() + "}]";
	}
	
	
}
